this.opacity = 0;
- Main.pushModal(global.stage, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
+ this._grab = Main.pushModal(global.stage, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
this.ease({
opacity: 255,
}
close() {
- Main.popModal(global.stage);
+ Main.popModal(this._grab);
+ this._grab = null;
Main.ctrlAltTabManager.removeGroup(this);
}
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
this._dragCancellable = true;
- this._eventsGrabbed = false;
this._capturedEventId = 0;
}
}
_grabEvents(device, touchSequence) {
- if (!this._eventsGrabbed) {
- this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
- if (this._eventsGrabbed)
+ if (!this._eventsGrab) {
+ let grab = Main.pushModal(_getEventHandlerActor());
+ if ((grab.get_seat_state() & Clutter.GrabState.POINTER) !== 0) {
this._grabDevice(_getEventHandlerActor(), device, touchSequence);
+ this._eventsGrab = grab;
+ } else {
+ Main.popModal(grab);
+ }
}
}
_ungrabEvents() {
- if (this._eventsGrabbed) {
+ if (this._eventsGrab) {
this._ungrabDevice();
- Main.popModal(_getEventHandlerActor());
- this._eventsGrabbed = false;
+ Main.popModal(this._eventsGrab);
+ this._eventsGrab = null;
}
}
_takeModalGrab() {
let firstGrab = this._modalCount == 0;
if (firstGrab) {
- if (!Main.pushModal(this._owner, this._modalParams))
+ let grab = Main.pushModal(this._owner, this._modalParams);
+ if (grab.get_seat_state() === Clutter.GrabState.NONE) {
+ Main.popModal(grab);
return false;
+ }
+ this._grab = grab;
this._capturedEventId = this._owner.connect('captured-event',
(actor, event) => {
return this.onCapturedEvent(event);
this._owner.disconnect(this._capturedEventId);
this._ignoreUntilRelease = false;
- Main.popModal(this._owner);
+ Main.popModal(this._grab);
+ this._grab = null;
}
// ignoreRelease:
if (this._open)
return;
- if (!Main.pushModal(this, { actionMode: Shell.ActionMode.LOOKING_GLASS }))
+ let grab = Main.pushModal(this, { actionMode: Shell.ActionMode.LOOKING_GLASS });
+ if (grab.get_seat_state() === Clutter.GrabState.NONE) {
+ Main.popModal(grab);
return;
+ }
+ this._grab = grab;
this._notebook.selectIndex(0);
this.show();
this._open = true;
duration,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
- Main.popModal(this);
+ Main.popModal(this._grab);
+ this._grab = null;
this.hide();
},
});
notify(msg, details);
}
-function _findModal(actor) {
+function _findModal(grab) {
for (let i = 0; i < modalActorFocusStack.length; i++) {
- if (modalActorFocusStack[i].actor == actor)
+ if (modalActorFocusStack[i].grab === grab)
return i;
}
return -1;
* global keybindings; the default of NONE will filter
* out all keybindings
*
- * @returns {bool}: true iff we successfully acquired a grab or already had one
+ * @returns {Clutter.Grab}: the grab handle created
*/
function pushModal(actor, params) {
params = Params.parse(params, { timestamp: global.get_current_time(),
modalCount += 1;
let actorDestroyId = actor.connect('destroy', () => {
- let index = _findModal(actor);
+ let index = _findModal(grab);
if (index >= 0)
- popModal(actor);
+ popModal(grab);
});
let prevFocus = global.stage.get_key_focus();
actionMode = params.actionMode;
global.stage.set_key_focus(actor);
- return true;
+ return grab;
}
/**
* popModal:
- * @param {Clutter.Actor} actor: the actor passed to original invocation
- * of pushModal()
- * @param {number=} timestamp: optional timestamp
+ * @param {Clutter.Grab} grab - the grab given by pushModal()
+ * @param {number=} timestamp - optional timestamp
*
* Reverse the effect of pushModal(). If this invocation is undoing
* the topmost invocation, then the focus will be restored to the
* initiated event. If not provided then the value of
* global.get_current_time() is assumed.
*/
-function popModal(actor, timestamp) {
+function popModal(grab, timestamp) {
if (timestamp == undefined)
timestamp = global.get_current_time();
- let focusIndex = _findModal(actor);
+ let focusIndex = _findModal(grab);
if (focusIndex < 0) {
global.stage.set_key_focus(null);
actionMode = Shell.ActionMode.NORMAL;
let record = modalActorFocusStack[focusIndex];
record.actor.disconnect(record.destroyId);
- let grab = record.grab;
- grab.dismiss();
+ record.grab.dismiss();
if (focusIndex == modalActorFocusStack.length - 1) {
if (record.prevFocus)
this._savedKeyFocus = focus;
else
this._savedKeyFocus = null;
- Main.popModal(this, timestamp);
+ Main.popModal(this._grab, timestamp);
+ this._grab = null;
this._hasModal = false;
if (!this._shellReactive)
let params = { actionMode: this._actionMode };
if (timestamp)
params['timestamp'] = timestamp;
- if (!Main.pushModal(this, params))
+ let grab = Main.pushModal(this, params);
+ if (grab.get_seat_state() === Clutter.GrabState.NONE) {
+ Main.popModal(grab);
return false;
+ }
+ this._grab = grab;
Main.layoutManager.emit('system-modal-opened');
this._hasModal = true;
let shouldBeModal = !this._inXdndDrag;
if (shouldBeModal && !this._modal) {
let actionMode = Shell.ActionMode.OVERVIEW;
- if (Main.pushModal(global.stage, { actionMode })) {
+ let grab = Main.pushModal(global.stage, { actionMode });
+ if (grab.get_seat_state() !== Clutter.GrabState.NONE) {
+ this._grab = grab;
this._modal = true;
} else {
+ Main.popModal(grab);
this.hide();
return false;
}
} else {
// eslint-disable-next-line no-lonely-if
if (this._modal) {
- Main.popModal(global.stage);
+ Main.popModal(this._grab);
+ this._grab = false;
this._modal = false;
}
}
buttonBox.add_actor(this._editButton);
this._syncEditionMode();
- Main.pushModal(this);
+ this._grab = Main.pushModal(this);
}
_updatePadChooser() {
}
_onDestroy() {
- Main.popModal(this);
+ Main.popModal(this._grab);
+ this._grab = null;
this._actionEditor.close();
let seat = Clutter.get_default_backend().get_default_seat();
}
removeMenu(menu) {
- if (menu == this.activeMenu)
- Main.popModal(menu.actor);
+ if (menu === this.activeMenu) {
+ Main.popModal(this._grab);
+ this._grab = null;
+ }
let position = this._findMenu(menu);
if (position == -1) // not a menu we manage
if (open) {
if (this.activeMenu)
this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
- Main.pushModal(menu.actor, this._grabParams);
+ this._grab = Main.pushModal(menu.actor, this._grabParams);
this.activeMenu = menu;
} else {
if (this.activeMenu === menu)
this.activeMenu = null;
- Main.popModal(menu.actor);
+ Main.popModal(this._grab);
+ this._grab = null;
}
}
if (this._isModal)
return true;
- this._isModal = Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOCK_SCREEN });
+ let grab = Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOCK_SCREEN });
+
+ // We expect at least a keyboard grab here
+ this._isModal = (grab.get_seat_state() & Clutter.GrabState.KEYBOARD) !== 0;
if (this._isModal)
- return true;
+ this._grab = grab;
+ else
+ Main.popModal(grab);
- // We failed to get a pointer grab, it means that
- // something else has it. Try with a keyboard grab only
- this._isModal = Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED,
- actionMode: Shell.ActionMode.LOCK_SCREEN });
return this._isModal;
}
this._dialog.popModal();
if (this._isModal) {
- Main.popModal(this.actor);
+ Main.popModal(this._grab);
+ this._grab = null;
this._isModal = false;
}
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported SwitcherPopup, SwitcherList */
-const { Clutter, GLib, GObject, Meta, St } = imports.gi;
+const { Clutter, GLib, GObject, St } = imports.gi;
const Main = imports.ui.main;
if (this._items.length == 0)
return false;
- if (!Main.pushModal(this)) {
- // Probably someone else has a pointer grab, try again with keyboard only
- if (!Main.pushModal(this, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED }))
- return false;
+ let grab = Main.pushModal(this);
+ // We expect at least a keyboard grab here
+ if ((grab.get_seat_state() & Clutter.GrabState.KEYBOARD) === 0) {
+ Main.popModal(grab);
+ return false;
}
+ this._grab = grab;
this._haveModal = true;
this._modifierMask = primaryModifier(mask);
_popModal() {
if (this._haveModal) {
- Main.popModal(this);
+ Main.popModal(this._grab);
+ this._grab = null;
this._haveModal = false;
}
}
timestamp,
actionMode: Shell.ActionMode.UNLOCK_SCREEN,
};
- if (!Main.pushModal(this, modalParams))
+ let grab = Main.pushModal(this, modalParams);
+ if (grab.get_seat_state() !== Clutter.GrabState.ALL) {
+ Main.popModal(grab);
return false;
+ }
+ this._grab = grab;
this._isModal = true;
return true;
popModal(timestamp) {
if (this._isModal) {
- Main.popModal(this, timestamp);
+ Main.popModal(this._grab, timestamp);
+ this._grab = null;
this._isModal = false;
}
}